package com.cwj.config.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.crypto.SecretKey;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class JwtAuthenticateFilter extends UsernamePasswordAuthenticationFilter {
    private static final String strKey = "RA1jvwoDtzFCi2JgVAHGNoxvPVUu/uBVnjjh215wpGQ=";
    private final AuthenticationManager authenticationManager;

    public JwtAuthenticateFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        setFilterProcessesUrl("/api/token");
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        LoginData loginData = null;
        try {
            loginData = pareData(request);
        } catch (IOException e) {
            e.printStackTrace();
        }
        UsernamePasswordAuthenticationToken uToken = new UsernamePasswordAuthenticationToken(loginData.getUserName(), loginData.getPassword());
        return this.authenticationManager.authenticate(uToken);
    }

    private LoginData pareData(HttpServletRequest request) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(request.getInputStream(),LoginData.class);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        User user = (User) authResult.getPrincipal();
        List<String> roles = user.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList());
        SecretKey key = Keys.hmacShaKeyFor(strKey.getBytes());
        String token = Jwts.builder()
                .setHeaderParam("TYP", "JWT")
                .setIssuer("setIssuer")
                .setAudience("setAudience")
                .setExpiration(new Date(System.currentTimeMillis() + 10000000))
                .setSubject(user.getUsername())
                .setIssuedAt(new Date())
                .setSubject(user.getUsername())
                .claim("rol", roles)
                .signWith(key).compact();
        response.setHeader("Authorization", "Bearer " + token);
    }
}
